import Request, { HttpRequestConfig, RequestTask } from 'luch-request'
import HttpResponse from '../models/http-response'
import storageConst from '../utils/storage-const'

/**
 * 网络请求基类
 */
export default class BaseService {
  private http = new Request()

  protected requestTask = new Array<RequestTask>()

  /**
   * 构造函数，request全局设置，请求拦截器，响应拦截器
   */
  constructor() {
    this.setConfig()
    this.http.interceptors.request.use(
      (config: HttpRequestConfig) => {
        // 可使用async await 做异步操作
        config.header = {
          ...config.header
        }
        if (config.custom?.auth) {
          config.header.token = uni.getStorageSync(storageConst.ACCESS_TOKEN)
        }
        return config
      },
      (config) => {
        // 可使用async await 做异步操作
        return Promise.reject(config)
      }
    )

    this.http.interceptors.response.use(
      (response) => {
        if (response.statusCode !== 200) {
          // 服务端返回的状态码不等于200，则reject()
          return Promise.reject(response) // return Promise.reject 可使promise状态进入catch
        }
        return response
      },
      (response) => {
        return Promise.reject(response)
      }
    )
  }

  /**
   * request全局配置
   */
  setConfig() {
    this.http.setConfig((config: HttpRequestConfig) => {
      // 服务地址
      config.baseURL = import.meta.env.VITE_BASE_URL
      config.timeout = 1000 * 60 * 10
      config.dataType = 'json'
      config.validateStatus = (statusCode) => {
        return statusCode >= 200 && statusCode < 500
      }
      return config
    })
  }

  /**
   * 基础请求方法
   * @param { HttpRequestConfig } config 请求配置
   * @param { string } method http method
   * @returns { T }
   */
  request<T>(
    config: HttpRequestConfig,
    method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'UPLOAD' | 'DOWNLOAD'
  ): Promise<HttpResponse<T>> {
    return new Promise((resolve) => {
      this.http
        .middleware({
          method,
          ...config,
          getTask: (task) => {
            this.requestTask.push(task as RequestTask)
          }
        })
        .then((response) => {
          resolve(
            new HttpResponse(
              response.statusCode,
              response.errMsg,
              response.data
            )
          )
        })
        .catch((reason) => {
          resolve(new HttpResponse(-1, '', reason))
        })
    })
  }

  /**
   * 取消历史请求
   */
  cancel() {
    for (const requestTask of this.requestTask) {
      requestTask.abort()
    }
  }

  /**
   * 新增资源
   * @param { string } url 资源地址
   * @param { any } data 资源实体
   * @param { object } custom 自定义实体，auth:true 需加token认证
   * @returns { T } T
   */
  post<T>(
    url: string,
    data: any,
    custom: { auth: boolean } = { auth: true }
  ): Promise<HttpResponse<T>> {
    return this.request<T>(
      {
        url,
        data,
        custom
      },
      'POST'
    )
  }

  /**
   * 获取资源
   * @param  { string } url 资源地址
   * @param  { any } params 查询参数
   * @param  { object } custom 自定义实体，auth:true 需加token认证
   * @returns { T } T
   */
  get<T>(
    url: string,
    params: any,
    custom: { auth: boolean } = { auth: true }
  ): Promise<HttpResponse<T>> {
    return this.request<T>(
      {
        url,
        params,
        custom
      },
      'GET'
    )
  }
}
